﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _8_1_Gather
{
    //集合 Array ArrayList  List Dictionary 

    public class MyDictionary : IDictionary
    {
        int[] array = new int[5];

        private KeyValuePair<object, object>[] kvps;
        //Dictionary<int, int> dic = new Dictionary<int, int>();
        private DictionaryEntry[] items;
        private int useItemsCount = 0;

        public MyDictionary(int length)
        {
            kvps = new KeyValuePair<object, object>[length];
            items = new DictionaryEntry[length];
        }
       
        #region Temp
        public class Temp
        {
            public bool isTrue;
            public int index;
            public Temp(int i, bool flag)
            {
                index = i;
                isTrue = flag;
            }
        }

        private Temp GetIndexOfKey1(object key)
        {
            for (int index = 0; index < useItemsCount; index++)
            {
                if (items[index].Key.Equals(key))
                    return new Temp(index, true);
            }
            return new Temp(-1, false);
        }

        private int GetIndexOfKey(object key)
        {
            for (int index = 0; index < useItemsCount; index++)
            {
                if (items[index].Key.Equals(key))
                    return index;
            }
            return -1;
        }
        #endregion



        public bool IsFixedSize
        {
            get
            {
                throw new NotImplementedException();
            }
        }

        public bool IsReadOnly
        {
            get
            {
                throw new NotImplementedException();
            }
        }

        public bool IsSynchronized
        {
            get
            {
                throw new NotImplementedException();
            }
        }

        public object SyncRoot
        {
            get
            {
                throw new NotImplementedException();
            }
        }

        #region Keys & Values
        public ICollection Keys
        {
            get
            {
                object[] keys = new object[useItemsCount];
                for (int i = 0; i < useItemsCount; i++)
                {
                    keys[i] = items[i].Key;
                }
                return keys;
            }
        }

        public ICollection Values
        {
            get
            {
                object[] values = new object[useItemsCount];
                for (int i = 0; i < useItemsCount; i++)
                {
                    values[i] = items[i].Value;
                }
                return values;
            }
        }

        #endregion


        public void Clear()
        {
            useItemsCount = 0;
        }

        public bool Contains(object key)
        {
            int index;
            return TryGetIndexOfKey(key, out index);
        }

        public void CopyTo(Array array, int index)
        {
            throw new NotImplementedException();
        }

        #region Add&Remove
        public void Add(object key, object value)
        {
            if (useItemsCount == items.Length)
                throw new InvalidOperationException("MyDictionary can not add item!");
            items[useItemsCount++] = new DictionaryEntry(key, value);
        }

        public void Remove(object key)
        {
            if (key == null)
                throw new ArgumentNullException("key is null");
            int index;
            if (TryGetIndexOfKey(key, out index))
            {
                Array.Copy(items, index + 1, items, index, useItemsCount - index - 1);
                useItemsCount--;
            }else
            {
                throw new InvalidOperationException("Not find this key");
            }

        }

        #endregion

        #region [] & Count
        public object this[object key]
        {
            get
            {
                int index;
                if (TryGetIndexOfKey(key, out index))
                {
                    return items[index].Value;
                }
                return null;
            }

            set
            {
                int index;
                if (TryGetIndexOfKey(key, out index))
                {
                    items[index].Value = value;
                }
                else
                {
                    Add(key, value);
                }
            }
        }

        private bool TryGetIndexOfKey(object key, out int index)
        {
            for (index = 0; index < useItemsCount; index++)
            {
                if (items[index].Key.Equals(key))
                    return true;
            }
            return false;
        }

        public int Count
        {
            get
            {
                return useItemsCount;
            }
        }

        #endregion


        IEnumerator IEnumerable.GetEnumerator()
        {
            return ((IDictionary)this).GetEnumerator();
        }

        public IDictionaryEnumerator GetEnumerator()
        {
            return new MyDictionaryEnumerator(this);
        }

        # region MyDictionaryEnumerator
        private class MyDictionaryEnumerator : IDictionaryEnumerator
        {
            DictionaryEntry[] items;
            int index = -1;

            public MyDictionaryEnumerator(MyDictionary dic)
            {
                items = new DictionaryEntry[dic.Count];
                Array.Copy(dic.items, 0, items, 0, dic.Count);
            }
            public object Current
            {
                get
                {
                    InvalidIndex();
                    return items[index];
                }
            }

            public DictionaryEntry Entry
            {
                get
                {
                    return (DictionaryEntry)Current;
                }
            }

            public object Key
            {
                get
                {
                    InvalidIndex();
                    return items[index].Key;
                }
            }

            public object Value
            {
                get
                {
                    InvalidIndex();
                    return items[index].Value;
                }
            }

            public bool MoveNext()
            {
                if (index < items.Length - 1)
                {
                    index++;
                    return true;
                }
                return false;
            }

            public void Reset()
            {
                index = -1;
            }

            private void InvalidIndex()
            {
                if (index < 0 || index >= items.Length)
                    throw new IndexOutOfRangeException("Error!");
            }
        }

        #endregion
    }

    class Program
    {
        static void Main(string[] args)
        {
            MyDictionary myDic = new MyDictionary(4);
            //key value
            myDic.Add(1, "111111");
            myDic.Add(2, "222222");
            myDic.Add(3, "333333");
            myDic.Add("111111", myDic);

            Console.WriteLine("Count : {0}", myDic.Count);
            Console.WriteLine("has key? : {0}", myDic.Contains("111111"));
            Console.WriteLine("has key? : {0}", myDic.Contains(1));
            Console.WriteLine("has key? : {0}", myDic["111111"]);

            foreach (DictionaryEntry item in myDic)
            {
                Console.WriteLine("Key: {0}, Value:{1}", item.Key, item.Value);
            }

            foreach (var item in myDic.Keys)
            {
                Console.WriteLine("key: {0}", item);

            }

            foreach (var item in myDic.Values)
            {
                Console.WriteLine("value: {0}", item);
            }

            myDic.Remove(1);

            foreach (DictionaryEntry item in myDic)
            {
                Console.WriteLine("Key: {0}, Value:{1}", item.Key, item.Value);
            }

            Console.ReadKey();

            AnimalTest.Test();

            Console.ReadKey();
        }
    }
}
